home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2000 October / PC-WELT 10-2000.ISO / software / boot / PCWBOOT.EXE / CMOS / CMOS.S < prev    next >
Encoding:
Text File  |  1999-05-05  |  29.6 KB  |  996 lines

  1. ;
  2. ;               CMOS.COM   v1.00   05-05-1999   Charles Dye
  3. ;               GPL Freeware   Copyright 1994-1999, C. Dye.
  4. ;                       email:  raster@highfiber.com
  5. ;
  6. ;       This file CMOS.S is a source file for Eric Isaacson's excellent
  7. ;       shareware assembler, A86.  Assemble by typing:  A86 CMOS.S
  8. ;
  9. ;       This program is copyrighted, but may be freely distributed
  10. ;       under the terms of the Free Software Foundation's GNU General
  11. ;       Public License v2 (or later.)  See the file COPYING for the
  12. ;       legalities.  If you did not receive a copy of COPYING, you
  13. ;       may request one from the Free Software Foundation, Inc.,
  14. ;       59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  15. ;       ABSOLUTELY NO WARRANTY -- use it at your own risk!
  16. ;
  17.  
  18. radix 16                               ; gentlemen prefer hex
  19.  
  20. jmp begin                              ; skip over variables
  21.  
  22. doscall macro                          ; call dos int 21 with a one-byte
  23. mov ah,#1                              ; function in .ah
  24. int 21
  25. #em
  26.  
  27. doscall2 macro                         ; call dos int 21 with a two-byte
  28. mov ax,#1                              ; function in .ax
  29. int 21
  30. #em
  31.  
  32. dosprint macro                         ; call dos string-print function
  33. mov dx,offset #1
  34. mov ah,09
  35. int 21
  36. #em
  37.  
  38. fnbuf:                                 ; holds filename
  39. db 41 dup 00
  40.  
  41. flags:                                 ; bit 7 = valid machine
  42. db 00                                  ; bit 6 = extended cmos (40 - 7F)
  43.                                        ; bit 5 = mca   ** not implemented **
  44.                                        ; bit 4 = eisa  ** not implemented **
  45.                                        ; bits 3-0 = undefined in format 1.0
  46.  
  47. len:                                   ; length of cmos data, incl. header
  48. dw 0000                                ; always 64 or 128 in this version
  49.  
  50. endpnt:
  51. dw 0000
  52.  
  53. csum:                                  ; checksum to verify file integrity
  54. dw 0000
  55.  
  56. hash:                                  ; hashtotal to verify file integrity
  57. dw 0000
  58.  
  59. handle:                                ; handle of data file
  60. dw 0000
  61.  
  62. ver_flag:                              ; flag:  0 = load, nonzero = verify
  63. db 00
  64.  
  65. reboot_flag:                           ; flag:  0 = reboot after cmos load,
  66. db 00                                  ; nonzero = please don't
  67.  
  68. misc:                                  ; miscellaneous byte variable
  69. db 00
  70.  
  71. model_word:                            ; machine model and submodel bytes
  72. dw 0000
  73.  
  74. begin:
  75. call machine_check
  76.  
  77. parse_cmd_line:
  78. mov si,0081
  79. parse:
  80. lodsb
  81. call chk_space
  82. je parse
  83. cmp al,'/'
  84. je parse
  85. cmp al,'-'
  86. je parse
  87. call forceuc
  88. mov bx,0000
  89. parse02:
  90. mov ah,b [switches+bx]
  91. cmp ah,00
  92. je parse04
  93. cmp al,ah
  94. je parse06
  95. inc bx
  96. jmp parse02
  97. parse04:
  98. jmp syntax
  99. parse06:
  100. shl bx,01
  101. mov ax,w [switch_routines+bx]
  102. jmp ax
  103.  
  104. _save:                                 ; /s (save) /b (backup) /w (write)
  105. call getfn                             ; read the filename from command line
  106. call crlf                              ; print a blank line
  107. call read_cmos                         ; read configuration from cmos to dram
  108. dosprint msg_saving                    ; print out the 'saving' message
  109. call print_fn                          ; and the filename
  110. mov w [buffer+0],'M' by 'C'
  111. mov w [buffer+2],'S' by 'O'            ; set up the file header:  'CMOS'
  112. mov b [buffer+4],10                    ; and file version i.d.  (1.0)
  113. mov al,b [flags]
  114. mov b [buffer+5],al                    ; flags byte
  115. mov ax,w [model_word]
  116. mov w [buffer+6],ax                    ; model and submodel
  117. mov ax,w [len]                         ; length of file data
  118. sub ax,000e                            ; (deduct 14 clock registers)
  119. mov w [buffer+8],ax                    ; and save in file header
  120. mov ax,w [csum]
  121. mov bx,w [hash]
  122. mov w [buffer+0a],ax                   ; checksum  of cmos data
  123. mov w [buffer+0c],bx                   ; hashtotal of cmos data
  124.  
  125. mov cx,0000                            ; file attributes (normal)
  126. mov dx,offset fnbuf                    ; and pointer to filename
  127. doscall 3c                             ; open with overwrite
  128. jnc _save02                            ; no error, continue
  129. jmp file_error                         ;   otherwise, do file error routine
  130. _save02:
  131. mov w [handle],ax                      ; stash file handle for later use
  132. mov bx,ax                              ; and move to bx for next function
  133. mov cx,w [len]                         ; number of bytes to write
  134. mov dx,offset buffer                   ; pointer to data buffer
  135. doscall 40                             ; dos:  write handle
  136. jnc _save03
  137. jmp file_error                         ;   error, complain
  138. _save03:
  139. cmp ax,cx                              ; all bytes written okay?
  140. je _save04                             ; no error, continue
  141. mov ax,000e                            ; otherwise, we're out of disk space:
  142. jmp file_error                         ; pretend this is dos error 14
  143. _save04:
  144. mov bx,w [handle]                      ; get the file handle for
  145. doscall 3e                             ; dos close handle function
  146. jnc _save05
  147. jmp file_error                         ;    error, complain
  148. _save05:
  149. dosprint msg_done                      ; print the 'no errors' message
  150. doscall2 4c00                          ; and exit with errorlevel 0
  151.  
  152. _xload:                                ; /i  (install:  load w/o reboot)
  153. mov b [ver_flag],00                    ; not verifying
  154. mov b [reboot_flag],40                 ; don't reboot
  155. jmp _load_main
  156. _load:                                 ; /l (load) or /r (restore)
  157. mov b [ver_flag],00                    ; not verifying
  158. mov b [reboot_flag],00                 ; do reboot
  159. jmp _load_main
  160. _ver:                                  ; /v (verify) or /c (compare)
  161. mov b [ver_flag],40                    ; verifying cmos against file
  162. _load_main:
  163. call getfn                             ; read filename from command line
  164. dosprint msg_loading                   ; print 'loading' message
  165. call print_fn                          ; and filename
  166. mov dx,offset fnbuf                    ; pointer to filename
  167. mov al,10                              ; file read, deny all sharing
  168. doscall 3d                             ; open existing file
  169. jnc _load01                            ; no error, continue
  170. jmp file_error                         ;    error, abort program
  171. _load01:
  172. mov w [handle],ax                      ; stash handle for future use
  173. mov bx,ax                              ; and move to bx for next function
  174. mov cx,000e                            ; read 14 bytes (CMOS file header)
  175. mov dx,offset buffer                   ; pointer to file buffer
  176. doscall 3f                             ; dos:  read handle
  177. jnc _load02
  178. jmp file_error                         ;    error, abort
  179. _load02:
  180. cmp ax,000e                            ; check number of bytes read
  181. je _load03                             ; if 14, all is well -- continue
  182. mov ax,0025                            ; hit end of file!
  183. jmp file_error                         ; pretend it's dos error 25
  184. _load03:
  185. cmp w [buffer+0],'M' by 'C'            ; check file header for 'CMOS'
  186. jne _load_bad1                         ; signature -- if it's not there,
  187. cmp w [buffer+2],'S' by 'O'            ; abort with an error message
  188. jne _load_bad1
  189. cmp b [buffer+4],10                    ; check file header version byte
  190. jne _load_bad5                         ; if it's not 10h, abort
  191. mov al,b [buffer+5]                    ; check file header flags byte
  192. test al,80                             ; top bit must be set
  193. je _load_bad2                          ; abort if it isn't
  194. test al,30                             ; bit 5 = mca, bit 4 = eisa
  195. jne _load_bad3                         ; abort if either is set
  196. test al,0f                             ; bits 0-3 are undefined
  197. jne _load_bad2                         ; abort if any are set
  198. mov b [flags],al                       ; flags byte okay:  stash it
  199. mov ax,w [buffer+6]                    ; get model and submodel from header:
  200. cmp ax,0000                            ; pre-0.92 always saved a zero,
  201. je _load04                             ; so consider a zero legal
  202. cmp ax,w [model_word]                  ; otherwise, test against this machine
  203. je _load04                             ; if it matches, continue
  204. jmp _load_bad4                         ; mismatch, bomb out!
  205.  
  206. _load_bad1:
  207. mov dx,offset msg_lbad1                ; no CMOS header
  208. jmp _load_badc
  209. _load_bad2:
  210. mov dx,offset msg_lbad2                ; bad flags byte
  211. jmp _load_badc
  212. _load_bad3:
  213. mov dx,offset msg_lbad3                ; no EISA/MCA support
  214. jmp _load_badc
  215. _load_bad4:
  216. mov dx,offset msg_lbad4                ; machine model mismatch
  217. jmp _load_badc
  218. _load_bad5:
  219. mov dx,offset msg_lbad5                ; file version not supported
  220. jmp _load_badc
  221. _load_bad6:
  222. mov dx,offset msg_lbad6                ; checksum mismatch
  223. jmp _load_badc
  224. _load_bad7:
  225. mov dx,offset msg_lbad7                ; hashtotal mismatch
  226. _load_badc:
  227. push dx
  228. call crlf
  229. pop dx
  230. mov ah,09                              ; print out error message
  231. int 21
  232. call crlf
  233. doscall2 4c05                          ; and abort (bad file format/chksum)
  234.  
  235. _load04:                               ; file header looks okay:
  236. mov bx,w [handle]                      ; file handle
  237. mov cx,w [buffer+8]                    ; number of bytes to load
  238. mov dx,offset buffer
  239. add dx,000e                            ; buffer, just past file header
  240. doscall 3f                             ; dos:  read handle
  241. jnc _load05
  242. jmp file_error                         ; probs, abort
  243. _load05:
  244. cmp ax,w [buffer+8]                    ; compare bytes read against header
  245. je _load06
  246. mov ax,0025                            ; read too few bytes:
  247. jmp file_error                         ; pretend this is dos error 25
  248. _load06:
  249. mov ax,w [buffer+8]                    ; bytes read from file
  250. add ax,000e                            ; add length of file header
  251. mov w [len],ax                         ; to get buffer length for checksum
  252. call checksum                          ; calculate checksum
  253. mov ax,w [csum]                        ; compare calculated checksum
  254. cmp ax,w [buffer+0a]                   ; against checksum from file header
  255. jne _load_bad6                         ; mismatch?  bomb out
  256. mov ax,w [hash]                        ; compare calculated hashtotal
  257. cmp ax,w [buffer+0c]                   ; against hashtotal from file header
  258. jne _load_bad7                         ; mismatch?  abort
  259.  
  260. mov bx,w [handle]                      ; checksums match -- get file handle
  261. doscall 3e                             ; for dos close handle function
  262. cmp b [ver_flag],00                    ; is this a verify operation?
  263. jne _ver01                             ; yes, do that instead
  264. call write_cmos                        ; write data back into cmos memory
  265. dosprint msg_done                      ; print happiness message
  266. call reboot                            ; reboot machine
  267. doscall2 4c00                          ; exit program
  268.  
  269. _ver01:
  270. dosprint msg_verify
  271. mov w [csum],0000                      ; checksum word holds mismatch count
  272. mov b [misc],00
  273. mov si,000e
  274. mov w [endpnt],0040                    ; assume last cmos byte is 63
  275. test b [flags],40                      ; check flags:  saved extended cmos?
  276. je ver01                               ; no, skip ahead
  277. mov w [endpnt],0080                    ; last cmos byte is really 127
  278. ver01:
  279. cli                                    ; no interrupts please
  280. mov ax,si                              ; copy cmos register number
  281. out 70,al                              ; into cmos address register
  282. call delay                             ; wait a sec
  283. in al,71                               ; get byte from cmos into al
  284. sti                                    ; interrupts okay now
  285. call delay                             ; wait a bit
  286. mov ah,b [buffer+si]                   ; get file byte in ah
  287. cmp al,ah                              ; verify cmos byte against file
  288. je ver04                               ; verify okay, move on to next byte
  289. push ax                                ; save the good and bad values
  290. inc w [csum]
  291. test b [ver_flag],01
  292. jne ver05
  293. dosprint msg_vermis1                   ; print 'cmos/file' message
  294. or b [ver_flag],01
  295. ver05:
  296. dosprint msg_space4
  297. mov cx,si
  298. call clout                             ; print out offending cmos address
  299. dosprint msg_space4
  300. pop cx
  301. push cx
  302. mov cl,ch
  303. call clout                             ; print out byte from file
  304. dosprint msg_space4
  305. pop cx
  306. call clout                             ; print out byte from cmos
  307. dosprint msg_space4
  308. inc b [misc]
  309. cmp b [misc],03
  310. jne ver04
  311. mov b [misc],00
  312. call crlf                              ; terminal line feed
  313. ver04:
  314. inc si                                 ; verify okay -- next cmos address:
  315. cmp si,w [endpnt]                      ; done yet?
  316. jne ver01                              ; no, loop back
  317. cmp w [csum],0000                      ; all done; check mismatch count
  318. jne ver06
  319. dosprint msg_ver_okay                  ; no mismatches:  print 'okay' message
  320. doscall2 4c00                          ; and exit
  321. ver06:                                 ; some mismatches:
  322. cmp b [misc],00
  323. je ver07
  324. call crlf                              ; print crlf if one is needed
  325. ver07:
  326. dosprint msg_vermis2                   ; print 'mismatch count' message
  327. mov ax,w [csum]
  328. call axout                             ; and number of mismatches
  329. call crlf                              ; terminal line feed
  330. doscall2 4c07                          ; exit with file verify error
  331.  
  332. _dump:                                 ; /d (dump)
  333. call crlf                              ; print a blank line
  334. call read_cmos                         ; read configuration from cmos to dram
  335. dosprint msg_dump_cmos                 ; print 'dump' message
  336. mov cx,w [model_word]
  337. call cxout                             ; print out machine model word
  338. dosprint msg_dump0                     ; print close bracket and newline
  339. mov bx,0010                            ; start at beginning of cmos
  340. dump02:
  341. test bx,000f                           ; start of line?
  342. jne dump03
  343. call crlf                              ; if so, start new line
  344. mov cx,bx
  345. call clout                             ; print out cmos address
  346. dosprint msg_dump1                     ; followed by a colon and a space
  347. dump03:
  348. mov cl,b [buffer+bx]                   ; get a byte from the cmos buffer
  349. call clout                             ; and print it out
  350. mov dl,20
  351. doscall 02                             ; followed by a space
  352. inc bx                                 ; next byte
  353. cmp bx,w [len]                         ; done with cmos dump yet?
  354. jb dump02                              ; if not, loop back for more
  355. call crlf                              ; if so, print a blank line
  356. doscall2 4c00                          ; and exit with no error
  357.  
  358. getfn:
  359. mov di,offset fnbuf
  360. getfn01:
  361. lodsb
  362. cmp al,0d
  363. je getfn11
  364. cmp al,00
  365. je getfn11
  366. call chk_colon
  367. jne getfn01
  368. getfn02:
  369. mov al,b [si]
  370. call chk_colon
  371. jne getfn04
  372. inc si
  373. jmp getfn02
  374. getfn04:
  375. lodsb
  376. call forceuc
  377. call chk_space
  378. je getfn10
  379. cmp al,0d
  380. je getfn10
  381. cmp al,'/'
  382. jne getfn05
  383. mov al,'\'
  384. getfn05:
  385. mov b [di],al
  386. inc di
  387. cmp di,(offset fnbuf + 40)
  388. ja getfn09
  389. jmp getfn04
  390. getfn09:
  391. dosprint msg_too_long
  392. doscall2 4c02
  393. getfn10:
  394. mov b [di],00
  395. cmp di,offset fnbuf
  396. je getfn11
  397. ret
  398. getfn11:
  399. push si
  400. mov si,offset default_fn
  401. getfn12:
  402. lodsb
  403. mov b [di],al
  404. inc di
  405. cmp al,00
  406. jne getfn12
  407. pop si
  408. ret
  409.  
  410. print_fn:
  411. push si
  412. mov si,offset fnbuf
  413. mov ah,02
  414. print_fn01:
  415. mov dl,b [si]
  416. inc si
  417. cmp dl,00
  418. je print_fn03
  419. int 21
  420. jmp print_fn01
  421. print_fn03:
  422. call crlf
  423. pop si
  424. ret
  425.  
  426. machine_check:
  427. cli
  428. mov al,0f                              ; read the shutdown byte
  429. out 70,al
  430. call delay
  431. in al,71                               ; from cmos
  432. sti
  433. cmp al,0ff                             ; if it contains 255,
  434. jne mack03
  435. dosprint msg_no_cmos                   ; cmos memory is probably not present:
  436. doscall2 4c04                          ; print an error message and abort
  437. mack03:
  438. mov bx,0000
  439. doscall2 3306                          ; check for dos versions 5.0+
  440. cmp bx,0000
  441. jne mack04                             ; later dos, okay
  442. doscall 30                             ; check for older dosses
  443. cmp al,02
  444. ja mack04                              ; dos 3.0 or higher, okay
  445. dosprint msg_old_dos                   ; dos before 3.0, print error message
  446. doscall2 4c08                          ; exit with errorlevel 8
  447. int 20                                 ; or with no errorlevel if that fails
  448. mack04:
  449. mov cx,sp
  450. sub cx,offset buffer                   ; figure memory available for buffer
  451. cmp cx,2300                            ; 8 3/4 kilobytes or more?
  452. jae mack05                             ; yes, continue
  453. push cx                                ; no, save buffer size
  454. dosprint msg_memsize                   ; print memory message
  455. pop cx
  456. call cxout                             ; and amount of memory available
  457. call crlf
  458. doscall2 4c03                          ; then abort
  459. mack05:
  460. mov b [flags],80                       ; indicate valid machine
  461. mov ah,0c0
  462. int 15                                 ; look for bios description block
  463. jc mack06
  464. mov ax,w [es:bx+0002]                  ; if present, get model from it
  465. mov w [model_word],ax
  466. jmp mack07
  467. mack06:                                ; no bios description block, so
  468. mov es,0f000
  469. mov ax,w [es:0fffe]                    ; get model word by peeking bios
  470. mov w [model_word],ax
  471. mack07:
  472. ret
  473.  
  474. read_cmos:
  475. mov si,007f                            ; assume 128 valid cmos locations
  476. rdc01:
  477. cli                                    ; disable interrupts and
  478. mov ax,si                              ; move the cmos address
  479. out 70,al                              ; into the cmos address register
  480. call delay                             ; and wait a bit
  481. in al,71                               ; get cmos value
  482. sti                                    ; and re-enable interrupts
  483. call delay                             ; wait a bit
  484. mov b [buffer+si],al                   ; stash value in table
  485. dec si
  486. cmp si,000d                            ; if not done,
  487. jne rdc01                              ; loop back for next byte
  488. dosprint msg_ca1                       ; display area 1 message
  489. or b [flags],40                        ; assume 128 valid cmos bytes
  490. mov w [len],0080
  491. mov si,003f
  492. rdc02:
  493. mov al,b [buffer+si]                   ; compare normal cmos byte
  494. cmp al,b [buffer+40+si]                ; against extended cmos byte
  495. jne rdc03                              ; mismatch, exit
  496. dec si
  497. cmp si,000d                            ; otherwise, try next lower byte
  498. jne rdc02
  499. and b [flags],0bf                      ; all match:  only 64 cmos bytes
  500. mov w [len],0040
  501. rdc03:
  502. test b [flags],40
  503. je rdc04
  504. dosprint msg_ca2                       ; display area 2 message
  505. rdc04:
  506. call checksum
  507. ret
  508.  
  509. write_cmos:
  510. cli                                    ; no interrupts please
  511. mov si,000e
  512. mov w [endpnt],0040                    ; assume last cmos byte is 63
  513. test b [flags],40                      ; check flags:  saved extended cmos?
  514. je wrc01                               ; no, skip ahead
  515. mov w [endpnt],0080                    ; last cmos byte is really 127
  516. wrc01:
  517. mov ax,si                              ; copy cmos register number
  518. out 70,al                              ; into cmos address register
  519. call delay                             ; wait a sec
  520. mov dh,10                              ; retry counter for cmos write/verify
  521. mov ah,b [buffer+si]                   ; get byte to write into cmos
  522. wrc02:
  523. mov al,ah
  524. out 71,al                              ; write byte to cmos data register
  525. call delay                             ; wait a bit
  526. push ax
  527. mov ax,si                              ; copy cmos register number
  528. out 70,al                              ; into cmos address register
  529. pop ax
  530. call delay                             ; wait a bit
  531. in al,71                               ; get byte from cmos data register
  532. call delay                             ; wait a bit
  533. cmp al,ah                              ; verify byte was written correctly
  534. je wrc04                               ; verify okay, move on to next byte
  535. dec dh                                 ; decrement retry counter
  536. jne wrc02                              ; last try?  if not, loop back
  537. sti
  538. push ax                                ; save the good and bad values
  539. dosprint msg_wrce1                     ; print out unhappy message
  540. mov cx,si
  541. call clout                             ; print out offending cmos address
  542. dosprint msg_wrce2
  543. pop cx
  544. push cx
  545. mov cl,ch
  546. call clout                             ; print out correct (write) value
  547. dosprint msg_wrce3
  548. pop cx
  549. call clout                             ; print out wrong (verify) value
  550. call crlf                              ; terminal line
  551. doscall2 4c06                          ; abort program
  552. wrc04:
  553. inc si                                 ; verify okay -- next cmos address:
  554. cmp si,w [endpnt]                      ; done yet?
  555. jne wrc01                              ; no, loop back
  556. sti
  557. ret
  558.  
  559. reboot:
  560. cmp b [reboot_flag],00
  561. jne keyb_cmd_x
  562. dosprint msg_reboot1
  563. mov es,0040
  564. mov w [es:0072],0000                   ; set for cold start
  565. doscall 0d                             ; flush dos buffers (and smartdrive)
  566. mov ah,40
  567. call long_pause
  568. mov ah,0fe                             ; keyboard controller 'reset' command
  569. mov cx,0100                            ; loop 256 times
  570. keyb_cmd1:
  571. in al,64                               ; check keyboard command port
  572. call delay
  573. test al,02                             ; ready to receive command?
  574. je keyb_cmd5                           ; yes, proceed
  575. loop keyb_cmd1                         ; no, loop back and try again
  576. dosprint msg_reboot2
  577. ret                                    ; time out
  578. keyb_cmd5:                             ; keyboard controller ready:
  579. mov al,ah
  580. out 64,al                              ; write command byte to port
  581. mov ah,30
  582. call long_pause
  583. dosprint msg_reboot2
  584. keyb_cmd_x:
  585. ret
  586.  
  587. delay:
  588. push cx
  589. mov cx,0100
  590. delay01:
  591. jmp > l10
  592. l10:
  593. dec cx
  594. jne delay01
  595. pop cx
  596. ret
  597.  
  598. long_pause:
  599. mov es,0040
  600. long01:
  601. mov al,b [es:006c]
  602. long02:
  603. cmp al,b [es:006c]
  604. je long02
  605. dec ah
  606. jne long01
  607. ret
  608.  
  609. checksum:
  610. mov w [csum],0000
  611. mov w [hash],0000
  612. mov si,000e
  613. csum01:
  614. mov al,b [buffer+si]
  615. mov ah,00
  616. add w [csum],ax
  617. inc si
  618. cmp si,w [len]
  619. jne csum01
  620. mov si,000e
  621. csum02:
  622. mov ax,w [buffer+si]
  623. xor w [hash],ax
  624. inc si
  625. inc si
  626. cmp si,w [len]
  627. jb csum02
  628. dosprint msg_csum
  629. mov cx,w [csum]
  630. call cxout
  631. dosprint msg_hash
  632. mov cx,w [hash]
  633. call cxout
  634. call crlf
  635. ret
  636.  
  637. cxout:                                 ; print value in cx to stdout as hex
  638. mov ah,02
  639. mov dl,ch
  640. shr dl,01
  641. shr dl,01
  642. shr dl,01
  643. shr dl,01
  644. call cxout02
  645. mov dl,ch
  646. and dl,0f
  647. call cxout02
  648. clout:
  649. mov ah,02
  650. mov dl,cl
  651. shr dl,01
  652. shr dl,01
  653. shr dl,01
  654. shr dl,01
  655. call cxout02
  656. mov dl,cl
  657. and dl,0f
  658. call cxout02
  659. ret
  660.  
  661. cxout02:
  662. cmp dl,09
  663. ja cxout03
  664. add dl,'0'
  665. jmp cxout04
  666. cxout03:
  667. add dl,37
  668. cxout04:
  669. int 21
  670. ret
  671.  
  672. axout:                                 ; print value in ax to stdout as dec
  673. mov dx,0000
  674. push dx
  675. mov cx,000a
  676. axout01:
  677. mov dx,0000
  678. div cx
  679. mov bx,dx
  680. add bx,'0'
  681. push bx
  682. cmp ax,0000
  683. jne axout01
  684. mov ah,02
  685. axout02:
  686. pop dx
  687. cmp dx,0000
  688. je axout03
  689. int 21
  690. jmp axout02
  691. axout03:
  692. ret
  693.  
  694. file_error:
  695. push ax
  696. mov bx,w [handle]
  697. cmp bx,0000
  698. je file_error00
  699. doscall 3e
  700. file_error00:
  701. call crlf
  702. pop ax
  703. mov si,0000
  704. file_error01:
  705. mov bx,w [err_code+si]
  706. cmp bx,0000
  707. je file_error05
  708. cmp bx,ax
  709. je file_error02
  710. inc si
  711. inc si
  712. jmp file_error01
  713. file_error02:
  714. mov dx,w [err_text+si]
  715. mov ah,09
  716. int 21
  717. call crlf
  718. doscall2 4c01
  719. file_error05:
  720. push ax
  721. dosprint msg_file_err
  722. pop cx
  723. call cxout
  724. call crlf
  725. doscall2 4c01
  726.  
  727. crlf:
  728. dosprint msg_crlf
  729. ret
  730.  
  731. syntax:                                ; syntax error in command-line args:
  732. dosprint msg_syntax                    ; print syntax message
  733. doscall2 4c02                          ; and exit
  734.  
  735. forceuc:
  736. cmp al,'a'
  737. jb forceuc01
  738. cmp al,'z'
  739. ja forceuc01
  740. and al,0df
  741. forceuc01:
  742. ret
  743.  
  744. chk_colon:
  745. cmp al,':'
  746. je chk_colon01
  747. cmp al,'='
  748. je chk_colon01
  749. chk_space:
  750. cmp al,20
  751. je chk_colon01
  752. cmp al,09
  753. chk_colon01:
  754. ret
  755.  
  756. switches:
  757. db 'SBWLRVCID',00
  758.  
  759. switch_routines:
  760. dw _save,_save,_save,_load,_load,_ver,_ver,_xload,_dump
  761.  
  762. err_code:
  763. dw 02,03,05,0e,0f,13,15,1d,1e,20,25,00
  764.  
  765. err_text:
  766. dw doserr02,doserr03,doserr05,doserr0e,doserr0f
  767. dw doserr13,doserr15,doserr1d,doserr1e,doserr20,doserr25
  768.  
  769. msg_markver:                           ; for mark aitchison's version utility
  770. db 'VeRsIoN=1.00',00
  771. db 'CoPyRiGhT=Copyright 1994-1999, Charles Dye',00
  772.  
  773. default_fn:
  774. db 'CMOS.SAV',00
  775.  
  776. msg_syntax:
  777. db 0d,0a
  778. db 'CMOS.COM   v1.00   05-05-1999   C. Dye   raster@highfiber.com',0d,0a
  779. db 'GPL Freeware.  Copyright 1994-1999, Charles Dye.  No warranty!',0d,0a
  780. db 0a
  781. db 'FreeDOS utility to save and restore CMOS memory.',0d,0a
  782. db 0a
  783. db 'CMOS /SAVE [filename]    Save CMOS RAM to file',0d,0a
  784. db 'CMOS /LOAD [filename]    Restore CMOS from file and reboot',0d,0a
  785. db 'CMOS /I    [filename]    Restore CMOS from file, do not reboot',0d,0a
  786. db 'CMOS /VER  [filename]    Compare CMOS against file',0d,0a
  787. db 'CMOS /DUMP               Hex dump of current CMOS data',0d,0a
  788. db 0a
  789. db 'If no filename is specified, CMOS.SAV will be used.  Switches may be',0d,0a
  790. db 'abbreviated to the first letter.',0d,0a
  791. db 0a
  792. db 'This program may be freely distributed under the terms of the Free',0d,0a
  793. db 'Software Foundation''s GNU General Public License, version 2; or, at',0d,0a
  794. db 'your option, any later version of that License.  See the file COPYING',0d,0a
  795. db 'for details.'
  796.  
  797. msg_crlf:
  798. db 0d,0a,'$'
  799.  
  800. msg_no_cmos:
  801. db 0d,0a
  802. db 'This machine does not appear to have CMOS memory!',0d,0a,'$'
  803.  
  804. msg_old_dos:
  805. db 0d,0a
  806. db 'Sorry, this program requires DOS v3.00 or higher.',0d,0a,'$'
  807.  
  808. msg_too_long:
  809. db 0d,0a
  810. db 'Filename is too long -- maximum of 64 characters!',0d,0a
  811. db '$'
  812.  
  813. msg_memsize:
  814. db 'Insufficient memory:  $'
  815.  
  816. msg_saving:
  817. db 'Saving CMOS to file $'
  818.  
  819. msg_loading:
  820. db 0d,0a
  821. db 'Loading CMOS from file $'
  822.  
  823. msg_verify:
  824. db 0d,0a
  825. db 'Verifying CMOS against file:  $'
  826.  
  827. msg_dump_cmos:
  828. db 0d,0a
  829. db 'Dump of current CMOS configuration:  [$'
  830.  
  831. msg_dump0:
  832. db ']',0d,0a,'$'
  833.  
  834. msg_vermis1:
  835. db 0d,0a,0a,'Address  File  CMOS   Address  File  CMOS   Address  File  CMOS',0d,0a,'$'
  836.  
  837. msg_vermis2:
  838. db 0d,0a,'Total mismatches:  $'
  839.  
  840. msg_ver_okay:
  841. db 'No mismatches.',0d,0a,'$'
  842.  
  843. msg_space4:
  844. db '    $'
  845.  
  846. msg_ca1:
  847. db 'Standard CMOS (0Eh-3Fh)',0d,0a,'$'
  848.  
  849. msg_ca2:
  850. db 'Extended CMOS (40h-7Fh)',0d,0a,'$'
  851.  
  852. ; msg_ca3:
  853. ; db 'EISA extended CMOS (8K)',0d,0a,'$'
  854.  
  855. ; msg_ca4:
  856. ; db 'MCA extended CMOS (2K)',0d,0a,'$'
  857.  
  858. msg_csum:
  859. db 0d,0a,'Checksum:  $'
  860.  
  861. msg_hash:
  862. db '   Hashtotal:  $'
  863.  
  864. msg_file_err:
  865. db 'Dos file I/O error $'
  866.  
  867. doserr02:
  868. db 'File not found$'
  869.  
  870. doserr03:
  871. db 'Path not found$'
  872.  
  873. doserr05:
  874. db 'Access denied$'
  875.  
  876. doserr0e:
  877. db 'Out of disk space$'
  878.  
  879. doserr0f:
  880. db 'Invalid drive$'
  881.  
  882. doserr13:
  883. db 'Disk is write-protected$'
  884.  
  885. doserr15:
  886. db 'Drive not ready$'
  887.  
  888. doserr1d:
  889. db 'Write error$'
  890.  
  891. doserr1e:
  892. db 'Read error$'
  893.  
  894. doserr20:
  895. db 'Sharing violation$'
  896.  
  897. doserr25:
  898. db 'File too short$'
  899.  
  900. msg_lbad1:
  901. db 'Not a CMOS file!$'
  902.  
  903. msg_lbad2:
  904. db 'Illegal flags byte!$'
  905.  
  906. msg_lbad3:
  907. db 'Sorry, this version does not support EISA/MCA CMOS!$'
  908.  
  909. msg_lbad4:
  910. db 'Machine ID word mismatch!$'
  911.  
  912. msg_lbad5:
  913. db 'Unable to handle that file format!$'
  914.  
  915. msg_lbad6:
  916. db 'Checksum mismatch!$'
  917.  
  918. msg_lbad7:
  919. db 'Hashtotal mismatch!$'
  920.  
  921. msg_wrce1:
  922. db 0d,0a,'Error writing CMOS byte $'
  923.  
  924. msg_wrce2:
  925. db ':  wrote $'
  926.  
  927. msg_wrce3:
  928. db ', read back $'
  929.  
  930. msg_dump1:
  931. db ':  $'
  932.  
  933. msg_reboot1:
  934. db 0d,0a,'Attempting to reboot machine ... $'
  935.  
  936. msg_reboot2:
  937. db 'Failed.',0d,0a
  938. db 'You should press Control-Alt-Delete to reboot now.',0d,0a,'$'
  939.  
  940. msg_done:
  941. db 'No errors encountered.',0d,0a,'$'
  942.  
  943. buffer:
  944.  
  945. ;
  946. ;   Errorlevels:
  947. ;
  948. ;   0 :  success
  949. ;   1 :  dos file error
  950. ;   2 :  syntax error, invalid switch or filename too long
  951. ;   3 :  not enough memory
  952. ;   4 :  no cmos?  hardware problem?
  953. ;   5 :  invalid or corrupt file
  954. ;   6 :  cmos write-verify mismatch.  hardware problem?
  955. ;   7 :  cmos - file data mismatch
  956. ;   8 :  bad dos
  957. ;
  958. ;
  959. ;   CMOS file format:
  960. ;
  961. ;   4 bytes  'CMOS' file type identifier
  962. ;   1 byte 10h      file version identifier (1.0)
  963. ;   1 byte          flags:  bit 7 = valid, bit 6 = extended cmos present
  964. ;   2 bytes         bios model and submodel bytes
  965. ;   1 word (n)      length of data (in bytes)
  966. ;   1 word          checksum of data  (sum of all bytes)
  967. ;   1 word          hashtotal of data (xor of all words)
  968. ;   n bytes         cmos data.  so far, n is always 50 or 114 decimal
  969. ;
  970. ;
  971. ;   Versions:
  972. ;
  973. ;   v0.90   11-09-1994
  974. ;           Initial release.
  975. ;
  976. ;   v0.91   11-23-1994
  977. ;           Fixes DELAY code.
  978. ;
  979. ;   v0.92   07-31-1996
  980. ;           Saves machine model/submodel bytes in the previously "reserved"
  981. ;           word of the file header.  Adds switches /W (Write, same as Save)
  982. ;           and /C (Compare, same as Verify).  Errorlevel for "not enough
  983. ;           memory" changed from 4 to 3.  Added errorlevel 8 for "bad dos."
  984. ;
  985. ;   v0.93   10-12-1996
  986. ;           A very trivial update, just because my email address has changed.
  987. ;           Adds the semi-useless /DUMP switch, and now indicates the
  988. ;           program's freeware status in the syntax message.
  989. ;
  990. ;   v1.00   05-05-1999
  991. ;           Cleanup for release with FreeDOS.  Fix for 8086/8088 CPUs (though
  992. ;   XTs didn't have CMOS :-)  Added strings for VERSION.EXE.  Treat nul on
  993. ;   command line as an end-of-line.  Documented /I and exit codes.  Changed
  994. ;   license to GPL.
  995.  
  996.